﻿// Accord Math Library
// The Accord.NET Framework
// http://accord-framework.net
//
// Copyright © César Souza, 2009-2017
// cesarsouza at gmail.com
//
//    This library is free software; you can redistribute it and/or
//    modify it under the terms of the GNU Lesser General Public
//    License as published by the Free Software Foundation; either
//    version 2.1 of the License, or (at your option) any later version.
//
//    This library is distributed in the hope that it will be useful,
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//    Lesser General Public License for more details.
//
//    You should have received a copy of the GNU Lesser General Public
//    License along with this library; if not, write to the Free Software
//    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
//

// ======================================================================
// This code has been generated by a tool; do not edit manually. Instead,
// edit the T4 template Matrix.Elementwise.tt so this file can be regenerated. 
// ======================================================================

namespace Accord.Math
{
    using System;
    using System.CodeDom.Compiler;
    using Accord.Math;
    using System.Runtime.CompilerServices;

    //[GeneratedCode("Accord.NET T4 Templates", "3.1")]
    public static partial class Matrix
    {

        /// <summary>
        ///   Vector sum.
        /// </summary>
        ///
        /// <param name="vector">A vector whose sum will be calculated.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static int Sum(this int[] vector)
        {
            int sum = 0;
            for (int i = 0; i < vector.Length; i++)
                sum = (int)(sum + (int)vector[i]);
            return sum;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static int Sum(this int[,] matrix)
        {
            int sum = 0;
            foreach (var v in matrix)
                sum = (int)(sum + (int)v);
            return sum;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sums will be calculated.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static int Sum(this int[][] matrix)
        {
            int sum = 0;
            for (int i = 0; i < matrix.Length; i++)
                for (int j = 0; j < matrix[i].Length; j++)
                    sum = (int)(sum + (int)matrix[i][j]);
            return sum;
        }


        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static int[] Sum(this int[][] matrix, int dimension)
        {
            var result = new int[Matrix.GetLength(matrix, dimension)];      
            return Sum(matrix, dimension, result);
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static int[] Sum(this int[,] matrix, int dimension)
        {
            var result = new int[Matrix.GetLength(matrix, dimension)];      
            return Sum(matrix, dimension, result);
        }
        

        /// <summary>
        ///   Vector product.
        /// </summary>
        ///
        /// <param name="vector">A vector whose product will be calculated.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static int Product(this int[] vector)
        {
            int sum = 1;
            for (int i = 0; i < vector.Length; i++)
                sum = (int)(sum * (int)vector[i]);
            return sum;
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static int Product(this int[,] matrix)
        {
            int sum = 1;
            foreach (var v in matrix)
                sum = (int)(sum * (int)v);
            return sum;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sums will be calculated.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static int Product(this int[][] matrix)
        {
            int sum = 1;
            for (int i = 0; i < matrix.Length; i++)
                for (int j = 0; j < matrix[i].Length; j++)
                    sum = (int)(sum * (int)matrix[i][j]);
            return sum;
        }


        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static int[] Product(this int[][] matrix, int dimension)
        {
            var result = new int[Matrix.GetLength(matrix, dimension)];      
            return Product(matrix, dimension, result);
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static int[] Product(this int[,] matrix, int dimension)
        {
            var result = new int[Matrix.GetLength(matrix, dimension)];      
            return Product(matrix, dimension, result);
        }
        

        /// <summary>
        ///   Vector sum.
        /// </summary>
        ///
        /// <param name="vector">A vector whose sum will be calculated.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static short Sum(this short[] vector)
        {
            short sum = 0;
            for (int i = 0; i < vector.Length; i++)
                sum = (short)(sum + (short)vector[i]);
            return sum;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static short Sum(this short[,] matrix)
        {
            short sum = 0;
            foreach (var v in matrix)
                sum = (short)(sum + (short)v);
            return sum;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sums will be calculated.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static short Sum(this short[][] matrix)
        {
            short sum = 0;
            for (int i = 0; i < matrix.Length; i++)
                for (int j = 0; j < matrix[i].Length; j++)
                    sum = (short)(sum + (short)matrix[i][j]);
            return sum;
        }


        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static short[] Sum(this short[][] matrix, int dimension)
        {
            var result = new short[Matrix.GetLength(matrix, dimension)];      
            return Sum(matrix, dimension, result);
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static short[] Sum(this short[,] matrix, int dimension)
        {
            var result = new short[Matrix.GetLength(matrix, dimension)];      
            return Sum(matrix, dimension, result);
        }
        

        /// <summary>
        ///   Vector product.
        /// </summary>
        ///
        /// <param name="vector">A vector whose product will be calculated.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static short Product(this short[] vector)
        {
            short sum = 1;
            for (int i = 0; i < vector.Length; i++)
                sum = (short)(sum * (short)vector[i]);
            return sum;
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static short Product(this short[,] matrix)
        {
            short sum = 1;
            foreach (var v in matrix)
                sum = (short)(sum * (short)v);
            return sum;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sums will be calculated.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static short Product(this short[][] matrix)
        {
            short sum = 1;
            for (int i = 0; i < matrix.Length; i++)
                for (int j = 0; j < matrix[i].Length; j++)
                    sum = (short)(sum * (short)matrix[i][j]);
            return sum;
        }


        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static short[] Product(this short[][] matrix, int dimension)
        {
            var result = new short[Matrix.GetLength(matrix, dimension)];      
            return Product(matrix, dimension, result);
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static short[] Product(this short[,] matrix, int dimension)
        {
            var result = new short[Matrix.GetLength(matrix, dimension)];      
            return Product(matrix, dimension, result);
        }
        

        /// <summary>
        ///   Vector sum.
        /// </summary>
        ///
        /// <param name="vector">A vector whose sum will be calculated.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static float Sum(this float[] vector)
        {
            float sum = 0;
            for (int i = 0; i < vector.Length; i++)
                sum = (float)(sum + (float)vector[i]);
            return sum;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static float Sum(this float[,] matrix)
        {
            float sum = 0;
            foreach (var v in matrix)
                sum = (float)(sum + (float)v);
            return sum;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sums will be calculated.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static float Sum(this float[][] matrix)
        {
            float sum = 0;
            for (int i = 0; i < matrix.Length; i++)
                for (int j = 0; j < matrix[i].Length; j++)
                    sum = (float)(sum + (float)matrix[i][j]);
            return sum;
        }


        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static float[] Sum(this float[][] matrix, int dimension)
        {
            var result = new float[Matrix.GetLength(matrix, dimension)];      
            return Sum(matrix, dimension, result);
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static float[] Sum(this float[,] matrix, int dimension)
        {
            var result = new float[Matrix.GetLength(matrix, dimension)];      
            return Sum(matrix, dimension, result);
        }
        

        /// <summary>
        ///   Vector product.
        /// </summary>
        ///
        /// <param name="vector">A vector whose product will be calculated.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static float Product(this float[] vector)
        {
            float sum = 1;
            for (int i = 0; i < vector.Length; i++)
                sum = (float)(sum * (float)vector[i]);
            return sum;
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static float Product(this float[,] matrix)
        {
            float sum = 1;
            foreach (var v in matrix)
                sum = (float)(sum * (float)v);
            return sum;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sums will be calculated.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static float Product(this float[][] matrix)
        {
            float sum = 1;
            for (int i = 0; i < matrix.Length; i++)
                for (int j = 0; j < matrix[i].Length; j++)
                    sum = (float)(sum * (float)matrix[i][j]);
            return sum;
        }


        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static float[] Product(this float[][] matrix, int dimension)
        {
            var result = new float[Matrix.GetLength(matrix, dimension)];      
            return Product(matrix, dimension, result);
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static float[] Product(this float[,] matrix, int dimension)
        {
            var result = new float[Matrix.GetLength(matrix, dimension)];      
            return Product(matrix, dimension, result);
        }
        

        /// <summary>
        ///   Vector sum.
        /// </summary>
        ///
        /// <param name="vector">A vector whose sum will be calculated.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static double Sum(this double[] vector)
        {
            double sum = 0;
            for (int i = 0; i < vector.Length; i++)
                sum = (double)(sum + (double)vector[i]);
            return sum;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static double Sum(this double[,] matrix)
        {
            double sum = 0;
            foreach (var v in matrix)
                sum = (double)(sum + (double)v);
            return sum;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sums will be calculated.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static double Sum(this double[][] matrix)
        {
            double sum = 0;
            for (int i = 0; i < matrix.Length; i++)
                for (int j = 0; j < matrix[i].Length; j++)
                    sum = (double)(sum + (double)matrix[i][j]);
            return sum;
        }


        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static double[] Sum(this double[][] matrix, int dimension)
        {
            var result = new double[Matrix.GetLength(matrix, dimension)];      
            return Sum(matrix, dimension, result);
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static double[] Sum(this double[,] matrix, int dimension)
        {
            var result = new double[Matrix.GetLength(matrix, dimension)];      
            return Sum(matrix, dimension, result);
        }
        

        /// <summary>
        ///   Vector product.
        /// </summary>
        ///
        /// <param name="vector">A vector whose product will be calculated.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static double Product(this double[] vector)
        {
            double sum = 1;
            for (int i = 0; i < vector.Length; i++)
                sum = (double)(sum * (double)vector[i]);
            return sum;
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static double Product(this double[,] matrix)
        {
            double sum = 1;
            foreach (var v in matrix)
                sum = (double)(sum * (double)v);
            return sum;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sums will be calculated.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static double Product(this double[][] matrix)
        {
            double sum = 1;
            for (int i = 0; i < matrix.Length; i++)
                for (int j = 0; j < matrix[i].Length; j++)
                    sum = (double)(sum * (double)matrix[i][j]);
            return sum;
        }


        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static double[] Product(this double[][] matrix, int dimension)
        {
            var result = new double[Matrix.GetLength(matrix, dimension)];      
            return Product(matrix, dimension, result);
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static double[] Product(this double[,] matrix, int dimension)
        {
            var result = new double[Matrix.GetLength(matrix, dimension)];      
            return Product(matrix, dimension, result);
        }
        

        /// <summary>
        ///   Vector sum.
        /// </summary>
        ///
        /// <param name="vector">A vector whose sum will be calculated.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static long Sum(this long[] vector)
        {
            long sum = 0;
            for (int i = 0; i < vector.Length; i++)
                sum = (long)(sum + (long)vector[i]);
            return sum;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static long Sum(this long[,] matrix)
        {
            long sum = 0;
            foreach (var v in matrix)
                sum = (long)(sum + (long)v);
            return sum;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sums will be calculated.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static long Sum(this long[][] matrix)
        {
            long sum = 0;
            for (int i = 0; i < matrix.Length; i++)
                for (int j = 0; j < matrix[i].Length; j++)
                    sum = (long)(sum + (long)matrix[i][j]);
            return sum;
        }


        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static long[] Sum(this long[][] matrix, int dimension)
        {
            var result = new long[Matrix.GetLength(matrix, dimension)];      
            return Sum(matrix, dimension, result);
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static long[] Sum(this long[,] matrix, int dimension)
        {
            var result = new long[Matrix.GetLength(matrix, dimension)];      
            return Sum(matrix, dimension, result);
        }
        

        /// <summary>
        ///   Vector product.
        /// </summary>
        ///
        /// <param name="vector">A vector whose product will be calculated.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static long Product(this long[] vector)
        {
            long sum = 1;
            for (int i = 0; i < vector.Length; i++)
                sum = (long)(sum * (long)vector[i]);
            return sum;
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static long Product(this long[,] matrix)
        {
            long sum = 1;
            foreach (var v in matrix)
                sum = (long)(sum * (long)v);
            return sum;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sums will be calculated.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static long Product(this long[][] matrix)
        {
            long sum = 1;
            for (int i = 0; i < matrix.Length; i++)
                for (int j = 0; j < matrix[i].Length; j++)
                    sum = (long)(sum * (long)matrix[i][j]);
            return sum;
        }


        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static long[] Product(this long[][] matrix, int dimension)
        {
            var result = new long[Matrix.GetLength(matrix, dimension)];      
            return Product(matrix, dimension, result);
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static long[] Product(this long[,] matrix, int dimension)
        {
            var result = new long[Matrix.GetLength(matrix, dimension)];      
            return Product(matrix, dimension, result);
        }
        

        /// <summary>
        ///   Vector sum.
        /// </summary>
        ///
        /// <param name="vector">A vector whose sum will be calculated.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static decimal Sum(this decimal[] vector)
        {
            decimal sum = 0;
            for (int i = 0; i < vector.Length; i++)
                sum = (decimal)(sum + (decimal)vector[i]);
            return sum;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static decimal Sum(this decimal[,] matrix)
        {
            decimal sum = 0;
            foreach (var v in matrix)
                sum = (decimal)(sum + (decimal)v);
            return sum;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sums will be calculated.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static decimal Sum(this decimal[][] matrix)
        {
            decimal sum = 0;
            for (int i = 0; i < matrix.Length; i++)
                for (int j = 0; j < matrix[i].Length; j++)
                    sum = (decimal)(sum + (decimal)matrix[i][j]);
            return sum;
        }


        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static decimal[] Sum(this decimal[][] matrix, int dimension)
        {
            var result = new decimal[Matrix.GetLength(matrix, dimension)];      
            return Sum(matrix, dimension, result);
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static decimal[] Sum(this decimal[,] matrix, int dimension)
        {
            var result = new decimal[Matrix.GetLength(matrix, dimension)];      
            return Sum(matrix, dimension, result);
        }
        

        /// <summary>
        ///   Vector product.
        /// </summary>
        ///
        /// <param name="vector">A vector whose product will be calculated.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static decimal Product(this decimal[] vector)
        {
            decimal sum = 1;
            for (int i = 0; i < vector.Length; i++)
                sum = (decimal)(sum * (decimal)vector[i]);
            return sum;
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static decimal Product(this decimal[,] matrix)
        {
            decimal sum = 1;
            foreach (var v in matrix)
                sum = (decimal)(sum * (decimal)v);
            return sum;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sums will be calculated.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static decimal Product(this decimal[][] matrix)
        {
            decimal sum = 1;
            for (int i = 0; i < matrix.Length; i++)
                for (int j = 0; j < matrix[i].Length; j++)
                    sum = (decimal)(sum * (decimal)matrix[i][j]);
            return sum;
        }


        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static decimal[] Product(this decimal[][] matrix, int dimension)
        {
            var result = new decimal[Matrix.GetLength(matrix, dimension)];      
            return Product(matrix, dimension, result);
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static decimal[] Product(this decimal[,] matrix, int dimension)
        {
            var result = new decimal[Matrix.GetLength(matrix, dimension)];      
            return Product(matrix, dimension, result);
        }
        

        /// <summary>
        ///   Vector sum.
        /// </summary>
        ///
        /// <param name="vector">A vector whose sum will be calculated.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static int Sum(this bool[] vector)
        {
            int sum = 0;
            for (int i = 0; i < vector.Length; i++)
                sum = (int)(sum + (vector[i] ? 1 : 0));
            return sum;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static int Sum(this bool[,] matrix)
        {
            int sum = 0;
            foreach (var v in matrix)
                sum = (int)(sum + (v ? 1 : 0));
            return sum;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sums will be calculated.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static int Sum(this bool[][] matrix)
        {
            int sum = 0;
            for (int i = 0; i < matrix.Length; i++)
                for (int j = 0; j < matrix[i].Length; j++)
                    sum = (int)(sum + (matrix[i][j] ? 1 : 0));
            return sum;
        }


        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static int[] Sum(this bool[][] matrix, int dimension)
        {
            var result = new int[Matrix.GetLength(matrix, dimension)];      
            return Sum(matrix, dimension, result);
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static int[] Sum(this bool[,] matrix, int dimension)
        {
            var result = new int[Matrix.GetLength(matrix, dimension)];      
            return Sum(matrix, dimension, result);
        }
        

        /// <summary>
        ///   Vector product.
        /// </summary>
        ///
        /// <param name="vector">A vector whose product will be calculated.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static int Product(this bool[] vector)
        {
            int sum = 1;
            for (int i = 0; i < vector.Length; i++)
                sum = (int)(sum * (vector[i] ? 1 : 0));
            return sum;
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static int Product(this bool[,] matrix)
        {
            int sum = 1;
            foreach (var v in matrix)
                sum = (int)(sum * (v ? 1 : 0));
            return sum;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sums will be calculated.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static int Product(this bool[][] matrix)
        {
            int sum = 1;
            for (int i = 0; i < matrix.Length; i++)
                for (int j = 0; j < matrix[i].Length; j++)
                    sum = (int)(sum * (matrix[i][j] ? 1 : 0));
            return sum;
        }


        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static int[] Product(this bool[][] matrix, int dimension)
        {
            var result = new int[Matrix.GetLength(matrix, dimension)];      
            return Product(matrix, dimension, result);
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static int[] Product(this bool[,] matrix, int dimension)
        {
            var result = new int[Matrix.GetLength(matrix, dimension)];      
            return Product(matrix, dimension, result);
        }
        
        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static int[] Sum(this int[][] matrix, int dimension, int[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.Length;
            int cols = matrix[0].Length;

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    int s = 0;
                    for (int i = 0; i < rows; i++)
                        s = (int)(s + (int)matrix[i][j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    int s = 0;
                    for (int i = 0; i < cols; i++)
                        s = (int)(s + (int)matrix[j][i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static int[] Sum(this int[,] matrix, int dimension, int[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.GetLength(0);
            int cols = matrix.GetLength(1);

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    int s = 0;
                    for (int i = 0; i < rows; i++)
                        s = (int)(s + (int)matrix[i, j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    int s = 0;
                    for (int i = 0; i < cols; i++)
                        s = (int)(s + (int)matrix[j, i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static int[] Product(this int[][] matrix, int dimension, int[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.Length;
            int cols = matrix[0].Length;

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    int s = 1;
                    for (int i = 0; i < rows; i++)
                        s = (int)(s * (int)matrix[i][j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    int s = 1;
                    for (int i = 0; i < cols; i++)
                        s = (int)(s * (int)matrix[j][i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static int[] Product(this int[,] matrix, int dimension, int[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.GetLength(0);
            int cols = matrix.GetLength(1);

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    int s = 1;
                    for (int i = 0; i < rows; i++)
                        s = (int)(s * (int)matrix[i, j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    int s = 1;
                    for (int i = 0; i < cols; i++)
                        s = (int)(s * (int)matrix[j, i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static short[] Sum(this int[][] matrix, int dimension, short[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.Length;
            int cols = matrix[0].Length;

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    short s = 0;
                    for (int i = 0; i < rows; i++)
                        s = (short)(s + (short)matrix[i][j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    short s = 0;
                    for (int i = 0; i < cols; i++)
                        s = (short)(s + (short)matrix[j][i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static short[] Sum(this int[,] matrix, int dimension, short[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.GetLength(0);
            int cols = matrix.GetLength(1);

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    short s = 0;
                    for (int i = 0; i < rows; i++)
                        s = (short)(s + (short)matrix[i, j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    short s = 0;
                    for (int i = 0; i < cols; i++)
                        s = (short)(s + (short)matrix[j, i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static short[] Product(this int[][] matrix, int dimension, short[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.Length;
            int cols = matrix[0].Length;

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    short s = 1;
                    for (int i = 0; i < rows; i++)
                        s = (short)(s * (short)matrix[i][j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    short s = 1;
                    for (int i = 0; i < cols; i++)
                        s = (short)(s * (short)matrix[j][i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static short[] Product(this int[,] matrix, int dimension, short[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.GetLength(0);
            int cols = matrix.GetLength(1);

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    short s = 1;
                    for (int i = 0; i < rows; i++)
                        s = (short)(s * (short)matrix[i, j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    short s = 1;
                    for (int i = 0; i < cols; i++)
                        s = (short)(s * (short)matrix[j, i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static float[] Sum(this int[][] matrix, int dimension, float[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.Length;
            int cols = matrix[0].Length;

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    float s = 0;
                    for (int i = 0; i < rows; i++)
                        s = (float)(s + (float)matrix[i][j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    float s = 0;
                    for (int i = 0; i < cols; i++)
                        s = (float)(s + (float)matrix[j][i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static float[] Sum(this int[,] matrix, int dimension, float[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.GetLength(0);
            int cols = matrix.GetLength(1);

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    float s = 0;
                    for (int i = 0; i < rows; i++)
                        s = (float)(s + (float)matrix[i, j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    float s = 0;
                    for (int i = 0; i < cols; i++)
                        s = (float)(s + (float)matrix[j, i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static float[] Product(this int[][] matrix, int dimension, float[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.Length;
            int cols = matrix[0].Length;

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    float s = 1;
                    for (int i = 0; i < rows; i++)
                        s = (float)(s * (float)matrix[i][j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    float s = 1;
                    for (int i = 0; i < cols; i++)
                        s = (float)(s * (float)matrix[j][i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static float[] Product(this int[,] matrix, int dimension, float[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.GetLength(0);
            int cols = matrix.GetLength(1);

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    float s = 1;
                    for (int i = 0; i < rows; i++)
                        s = (float)(s * (float)matrix[i, j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    float s = 1;
                    for (int i = 0; i < cols; i++)
                        s = (float)(s * (float)matrix[j, i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static double[] Sum(this int[][] matrix, int dimension, double[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.Length;
            int cols = matrix[0].Length;

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    double s = 0;
                    for (int i = 0; i < rows; i++)
                        s = (double)(s + (double)matrix[i][j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    double s = 0;
                    for (int i = 0; i < cols; i++)
                        s = (double)(s + (double)matrix[j][i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static double[] Sum(this int[,] matrix, int dimension, double[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.GetLength(0);
            int cols = matrix.GetLength(1);

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    double s = 0;
                    for (int i = 0; i < rows; i++)
                        s = (double)(s + (double)matrix[i, j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    double s = 0;
                    for (int i = 0; i < cols; i++)
                        s = (double)(s + (double)matrix[j, i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static double[] Product(this int[][] matrix, int dimension, double[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.Length;
            int cols = matrix[0].Length;

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    double s = 1;
                    for (int i = 0; i < rows; i++)
                        s = (double)(s * (double)matrix[i][j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    double s = 1;
                    for (int i = 0; i < cols; i++)
                        s = (double)(s * (double)matrix[j][i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static double[] Product(this int[,] matrix, int dimension, double[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.GetLength(0);
            int cols = matrix.GetLength(1);

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    double s = 1;
                    for (int i = 0; i < rows; i++)
                        s = (double)(s * (double)matrix[i, j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    double s = 1;
                    for (int i = 0; i < cols; i++)
                        s = (double)(s * (double)matrix[j, i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static long[] Sum(this int[][] matrix, int dimension, long[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.Length;
            int cols = matrix[0].Length;

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    long s = 0;
                    for (int i = 0; i < rows; i++)
                        s = (long)(s + (long)matrix[i][j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    long s = 0;
                    for (int i = 0; i < cols; i++)
                        s = (long)(s + (long)matrix[j][i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static long[] Sum(this int[,] matrix, int dimension, long[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.GetLength(0);
            int cols = matrix.GetLength(1);

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    long s = 0;
                    for (int i = 0; i < rows; i++)
                        s = (long)(s + (long)matrix[i, j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    long s = 0;
                    for (int i = 0; i < cols; i++)
                        s = (long)(s + (long)matrix[j, i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static long[] Product(this int[][] matrix, int dimension, long[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.Length;
            int cols = matrix[0].Length;

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    long s = 1;
                    for (int i = 0; i < rows; i++)
                        s = (long)(s * (long)matrix[i][j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    long s = 1;
                    for (int i = 0; i < cols; i++)
                        s = (long)(s * (long)matrix[j][i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static long[] Product(this int[,] matrix, int dimension, long[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.GetLength(0);
            int cols = matrix.GetLength(1);

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    long s = 1;
                    for (int i = 0; i < rows; i++)
                        s = (long)(s * (long)matrix[i, j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    long s = 1;
                    for (int i = 0; i < cols; i++)
                        s = (long)(s * (long)matrix[j, i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static decimal[] Sum(this int[][] matrix, int dimension, decimal[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.Length;
            int cols = matrix[0].Length;

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    decimal s = 0;
                    for (int i = 0; i < rows; i++)
                        s = (decimal)(s + (decimal)matrix[i][j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    decimal s = 0;
                    for (int i = 0; i < cols; i++)
                        s = (decimal)(s + (decimal)matrix[j][i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static decimal[] Sum(this int[,] matrix, int dimension, decimal[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.GetLength(0);
            int cols = matrix.GetLength(1);

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    decimal s = 0;
                    for (int i = 0; i < rows; i++)
                        s = (decimal)(s + (decimal)matrix[i, j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    decimal s = 0;
                    for (int i = 0; i < cols; i++)
                        s = (decimal)(s + (decimal)matrix[j, i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static decimal[] Product(this int[][] matrix, int dimension, decimal[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.Length;
            int cols = matrix[0].Length;

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    decimal s = 1;
                    for (int i = 0; i < rows; i++)
                        s = (decimal)(s * (decimal)matrix[i][j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    decimal s = 1;
                    for (int i = 0; i < cols; i++)
                        s = (decimal)(s * (decimal)matrix[j][i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static decimal[] Product(this int[,] matrix, int dimension, decimal[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.GetLength(0);
            int cols = matrix.GetLength(1);

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    decimal s = 1;
                    for (int i = 0; i < rows; i++)
                        s = (decimal)(s * (decimal)matrix[i, j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    decimal s = 1;
                    for (int i = 0; i < cols; i++)
                        s = (decimal)(s * (decimal)matrix[j, i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static int[] Sum(this short[][] matrix, int dimension, int[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.Length;
            int cols = matrix[0].Length;

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    int s = 0;
                    for (int i = 0; i < rows; i++)
                        s = (int)(s + (int)matrix[i][j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    int s = 0;
                    for (int i = 0; i < cols; i++)
                        s = (int)(s + (int)matrix[j][i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static int[] Sum(this short[,] matrix, int dimension, int[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.GetLength(0);
            int cols = matrix.GetLength(1);

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    int s = 0;
                    for (int i = 0; i < rows; i++)
                        s = (int)(s + (int)matrix[i, j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    int s = 0;
                    for (int i = 0; i < cols; i++)
                        s = (int)(s + (int)matrix[j, i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static int[] Product(this short[][] matrix, int dimension, int[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.Length;
            int cols = matrix[0].Length;

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    int s = 1;
                    for (int i = 0; i < rows; i++)
                        s = (int)(s * (int)matrix[i][j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    int s = 1;
                    for (int i = 0; i < cols; i++)
                        s = (int)(s * (int)matrix[j][i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static int[] Product(this short[,] matrix, int dimension, int[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.GetLength(0);
            int cols = matrix.GetLength(1);

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    int s = 1;
                    for (int i = 0; i < rows; i++)
                        s = (int)(s * (int)matrix[i, j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    int s = 1;
                    for (int i = 0; i < cols; i++)
                        s = (int)(s * (int)matrix[j, i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static short[] Sum(this short[][] matrix, int dimension, short[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.Length;
            int cols = matrix[0].Length;

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    short s = 0;
                    for (int i = 0; i < rows; i++)
                        s = (short)(s + (short)matrix[i][j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    short s = 0;
                    for (int i = 0; i < cols; i++)
                        s = (short)(s + (short)matrix[j][i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static short[] Sum(this short[,] matrix, int dimension, short[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.GetLength(0);
            int cols = matrix.GetLength(1);

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    short s = 0;
                    for (int i = 0; i < rows; i++)
                        s = (short)(s + (short)matrix[i, j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    short s = 0;
                    for (int i = 0; i < cols; i++)
                        s = (short)(s + (short)matrix[j, i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static short[] Product(this short[][] matrix, int dimension, short[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.Length;
            int cols = matrix[0].Length;

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    short s = 1;
                    for (int i = 0; i < rows; i++)
                        s = (short)(s * (short)matrix[i][j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    short s = 1;
                    for (int i = 0; i < cols; i++)
                        s = (short)(s * (short)matrix[j][i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static short[] Product(this short[,] matrix, int dimension, short[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.GetLength(0);
            int cols = matrix.GetLength(1);

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    short s = 1;
                    for (int i = 0; i < rows; i++)
                        s = (short)(s * (short)matrix[i, j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    short s = 1;
                    for (int i = 0; i < cols; i++)
                        s = (short)(s * (short)matrix[j, i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static float[] Sum(this short[][] matrix, int dimension, float[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.Length;
            int cols = matrix[0].Length;

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    float s = 0;
                    for (int i = 0; i < rows; i++)
                        s = (float)(s + (float)matrix[i][j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    float s = 0;
                    for (int i = 0; i < cols; i++)
                        s = (float)(s + (float)matrix[j][i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static float[] Sum(this short[,] matrix, int dimension, float[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.GetLength(0);
            int cols = matrix.GetLength(1);

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    float s = 0;
                    for (int i = 0; i < rows; i++)
                        s = (float)(s + (float)matrix[i, j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    float s = 0;
                    for (int i = 0; i < cols; i++)
                        s = (float)(s + (float)matrix[j, i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static float[] Product(this short[][] matrix, int dimension, float[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.Length;
            int cols = matrix[0].Length;

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    float s = 1;
                    for (int i = 0; i < rows; i++)
                        s = (float)(s * (float)matrix[i][j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    float s = 1;
                    for (int i = 0; i < cols; i++)
                        s = (float)(s * (float)matrix[j][i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static float[] Product(this short[,] matrix, int dimension, float[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.GetLength(0);
            int cols = matrix.GetLength(1);

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    float s = 1;
                    for (int i = 0; i < rows; i++)
                        s = (float)(s * (float)matrix[i, j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    float s = 1;
                    for (int i = 0; i < cols; i++)
                        s = (float)(s * (float)matrix[j, i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static double[] Sum(this short[][] matrix, int dimension, double[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.Length;
            int cols = matrix[0].Length;

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    double s = 0;
                    for (int i = 0; i < rows; i++)
                        s = (double)(s + (double)matrix[i][j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    double s = 0;
                    for (int i = 0; i < cols; i++)
                        s = (double)(s + (double)matrix[j][i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static double[] Sum(this short[,] matrix, int dimension, double[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.GetLength(0);
            int cols = matrix.GetLength(1);

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    double s = 0;
                    for (int i = 0; i < rows; i++)
                        s = (double)(s + (double)matrix[i, j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    double s = 0;
                    for (int i = 0; i < cols; i++)
                        s = (double)(s + (double)matrix[j, i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static double[] Product(this short[][] matrix, int dimension, double[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.Length;
            int cols = matrix[0].Length;

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    double s = 1;
                    for (int i = 0; i < rows; i++)
                        s = (double)(s * (double)matrix[i][j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    double s = 1;
                    for (int i = 0; i < cols; i++)
                        s = (double)(s * (double)matrix[j][i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static double[] Product(this short[,] matrix, int dimension, double[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.GetLength(0);
            int cols = matrix.GetLength(1);

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    double s = 1;
                    for (int i = 0; i < rows; i++)
                        s = (double)(s * (double)matrix[i, j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    double s = 1;
                    for (int i = 0; i < cols; i++)
                        s = (double)(s * (double)matrix[j, i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static long[] Sum(this short[][] matrix, int dimension, long[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.Length;
            int cols = matrix[0].Length;

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    long s = 0;
                    for (int i = 0; i < rows; i++)
                        s = (long)(s + (long)matrix[i][j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    long s = 0;
                    for (int i = 0; i < cols; i++)
                        s = (long)(s + (long)matrix[j][i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static long[] Sum(this short[,] matrix, int dimension, long[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.GetLength(0);
            int cols = matrix.GetLength(1);

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    long s = 0;
                    for (int i = 0; i < rows; i++)
                        s = (long)(s + (long)matrix[i, j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    long s = 0;
                    for (int i = 0; i < cols; i++)
                        s = (long)(s + (long)matrix[j, i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static long[] Product(this short[][] matrix, int dimension, long[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.Length;
            int cols = matrix[0].Length;

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    long s = 1;
                    for (int i = 0; i < rows; i++)
                        s = (long)(s * (long)matrix[i][j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    long s = 1;
                    for (int i = 0; i < cols; i++)
                        s = (long)(s * (long)matrix[j][i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static long[] Product(this short[,] matrix, int dimension, long[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.GetLength(0);
            int cols = matrix.GetLength(1);

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    long s = 1;
                    for (int i = 0; i < rows; i++)
                        s = (long)(s * (long)matrix[i, j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    long s = 1;
                    for (int i = 0; i < cols; i++)
                        s = (long)(s * (long)matrix[j, i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static decimal[] Sum(this short[][] matrix, int dimension, decimal[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.Length;
            int cols = matrix[0].Length;

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    decimal s = 0;
                    for (int i = 0; i < rows; i++)
                        s = (decimal)(s + (decimal)matrix[i][j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    decimal s = 0;
                    for (int i = 0; i < cols; i++)
                        s = (decimal)(s + (decimal)matrix[j][i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static decimal[] Sum(this short[,] matrix, int dimension, decimal[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.GetLength(0);
            int cols = matrix.GetLength(1);

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    decimal s = 0;
                    for (int i = 0; i < rows; i++)
                        s = (decimal)(s + (decimal)matrix[i, j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    decimal s = 0;
                    for (int i = 0; i < cols; i++)
                        s = (decimal)(s + (decimal)matrix[j, i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static decimal[] Product(this short[][] matrix, int dimension, decimal[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.Length;
            int cols = matrix[0].Length;

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    decimal s = 1;
                    for (int i = 0; i < rows; i++)
                        s = (decimal)(s * (decimal)matrix[i][j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    decimal s = 1;
                    for (int i = 0; i < cols; i++)
                        s = (decimal)(s * (decimal)matrix[j][i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static decimal[] Product(this short[,] matrix, int dimension, decimal[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.GetLength(0);
            int cols = matrix.GetLength(1);

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    decimal s = 1;
                    for (int i = 0; i < rows; i++)
                        s = (decimal)(s * (decimal)matrix[i, j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    decimal s = 1;
                    for (int i = 0; i < cols; i++)
                        s = (decimal)(s * (decimal)matrix[j, i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static int[] Sum(this float[][] matrix, int dimension, int[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.Length;
            int cols = matrix[0].Length;

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    int s = 0;
                    for (int i = 0; i < rows; i++)
                        s = (int)(s + (int)matrix[i][j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    int s = 0;
                    for (int i = 0; i < cols; i++)
                        s = (int)(s + (int)matrix[j][i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static int[] Sum(this float[,] matrix, int dimension, int[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.GetLength(0);
            int cols = matrix.GetLength(1);

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    int s = 0;
                    for (int i = 0; i < rows; i++)
                        s = (int)(s + (int)matrix[i, j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    int s = 0;
                    for (int i = 0; i < cols; i++)
                        s = (int)(s + (int)matrix[j, i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static int[] Product(this float[][] matrix, int dimension, int[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.Length;
            int cols = matrix[0].Length;

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    int s = 1;
                    for (int i = 0; i < rows; i++)
                        s = (int)(s * (int)matrix[i][j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    int s = 1;
                    for (int i = 0; i < cols; i++)
                        s = (int)(s * (int)matrix[j][i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static int[] Product(this float[,] matrix, int dimension, int[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.GetLength(0);
            int cols = matrix.GetLength(1);

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    int s = 1;
                    for (int i = 0; i < rows; i++)
                        s = (int)(s * (int)matrix[i, j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    int s = 1;
                    for (int i = 0; i < cols; i++)
                        s = (int)(s * (int)matrix[j, i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static short[] Sum(this float[][] matrix, int dimension, short[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.Length;
            int cols = matrix[0].Length;

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    short s = 0;
                    for (int i = 0; i < rows; i++)
                        s = (short)(s + (short)matrix[i][j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    short s = 0;
                    for (int i = 0; i < cols; i++)
                        s = (short)(s + (short)matrix[j][i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static short[] Sum(this float[,] matrix, int dimension, short[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.GetLength(0);
            int cols = matrix.GetLength(1);

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    short s = 0;
                    for (int i = 0; i < rows; i++)
                        s = (short)(s + (short)matrix[i, j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    short s = 0;
                    for (int i = 0; i < cols; i++)
                        s = (short)(s + (short)matrix[j, i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static short[] Product(this float[][] matrix, int dimension, short[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.Length;
            int cols = matrix[0].Length;

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    short s = 1;
                    for (int i = 0; i < rows; i++)
                        s = (short)(s * (short)matrix[i][j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    short s = 1;
                    for (int i = 0; i < cols; i++)
                        s = (short)(s * (short)matrix[j][i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static short[] Product(this float[,] matrix, int dimension, short[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.GetLength(0);
            int cols = matrix.GetLength(1);

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    short s = 1;
                    for (int i = 0; i < rows; i++)
                        s = (short)(s * (short)matrix[i, j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    short s = 1;
                    for (int i = 0; i < cols; i++)
                        s = (short)(s * (short)matrix[j, i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static float[] Sum(this float[][] matrix, int dimension, float[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.Length;
            int cols = matrix[0].Length;

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    float s = 0;
                    for (int i = 0; i < rows; i++)
                        s = (float)(s + (float)matrix[i][j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    float s = 0;
                    for (int i = 0; i < cols; i++)
                        s = (float)(s + (float)matrix[j][i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static float[] Sum(this float[,] matrix, int dimension, float[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.GetLength(0);
            int cols = matrix.GetLength(1);

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    float s = 0;
                    for (int i = 0; i < rows; i++)
                        s = (float)(s + (float)matrix[i, j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    float s = 0;
                    for (int i = 0; i < cols; i++)
                        s = (float)(s + (float)matrix[j, i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static float[] Product(this float[][] matrix, int dimension, float[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.Length;
            int cols = matrix[0].Length;

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    float s = 1;
                    for (int i = 0; i < rows; i++)
                        s = (float)(s * (float)matrix[i][j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    float s = 1;
                    for (int i = 0; i < cols; i++)
                        s = (float)(s * (float)matrix[j][i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static float[] Product(this float[,] matrix, int dimension, float[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.GetLength(0);
            int cols = matrix.GetLength(1);

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    float s = 1;
                    for (int i = 0; i < rows; i++)
                        s = (float)(s * (float)matrix[i, j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    float s = 1;
                    for (int i = 0; i < cols; i++)
                        s = (float)(s * (float)matrix[j, i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static double[] Sum(this float[][] matrix, int dimension, double[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.Length;
            int cols = matrix[0].Length;

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    double s = 0;
                    for (int i = 0; i < rows; i++)
                        s = (double)(s + (double)matrix[i][j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    double s = 0;
                    for (int i = 0; i < cols; i++)
                        s = (double)(s + (double)matrix[j][i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static double[] Sum(this float[,] matrix, int dimension, double[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.GetLength(0);
            int cols = matrix.GetLength(1);

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    double s = 0;
                    for (int i = 0; i < rows; i++)
                        s = (double)(s + (double)matrix[i, j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    double s = 0;
                    for (int i = 0; i < cols; i++)
                        s = (double)(s + (double)matrix[j, i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static double[] Product(this float[][] matrix, int dimension, double[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.Length;
            int cols = matrix[0].Length;

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    double s = 1;
                    for (int i = 0; i < rows; i++)
                        s = (double)(s * (double)matrix[i][j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    double s = 1;
                    for (int i = 0; i < cols; i++)
                        s = (double)(s * (double)matrix[j][i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static double[] Product(this float[,] matrix, int dimension, double[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.GetLength(0);
            int cols = matrix.GetLength(1);

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    double s = 1;
                    for (int i = 0; i < rows; i++)
                        s = (double)(s * (double)matrix[i, j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    double s = 1;
                    for (int i = 0; i < cols; i++)
                        s = (double)(s * (double)matrix[j, i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static long[] Sum(this float[][] matrix, int dimension, long[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.Length;
            int cols = matrix[0].Length;

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    long s = 0;
                    for (int i = 0; i < rows; i++)
                        s = (long)(s + (long)matrix[i][j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    long s = 0;
                    for (int i = 0; i < cols; i++)
                        s = (long)(s + (long)matrix[j][i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static long[] Sum(this float[,] matrix, int dimension, long[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.GetLength(0);
            int cols = matrix.GetLength(1);

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    long s = 0;
                    for (int i = 0; i < rows; i++)
                        s = (long)(s + (long)matrix[i, j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    long s = 0;
                    for (int i = 0; i < cols; i++)
                        s = (long)(s + (long)matrix[j, i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static long[] Product(this float[][] matrix, int dimension, long[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.Length;
            int cols = matrix[0].Length;

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    long s = 1;
                    for (int i = 0; i < rows; i++)
                        s = (long)(s * (long)matrix[i][j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    long s = 1;
                    for (int i = 0; i < cols; i++)
                        s = (long)(s * (long)matrix[j][i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static long[] Product(this float[,] matrix, int dimension, long[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.GetLength(0);
            int cols = matrix.GetLength(1);

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    long s = 1;
                    for (int i = 0; i < rows; i++)
                        s = (long)(s * (long)matrix[i, j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    long s = 1;
                    for (int i = 0; i < cols; i++)
                        s = (long)(s * (long)matrix[j, i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static decimal[] Sum(this float[][] matrix, int dimension, decimal[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.Length;
            int cols = matrix[0].Length;

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    decimal s = 0;
                    for (int i = 0; i < rows; i++)
                        s = (decimal)(s + (decimal)matrix[i][j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    decimal s = 0;
                    for (int i = 0; i < cols; i++)
                        s = (decimal)(s + (decimal)matrix[j][i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static decimal[] Sum(this float[,] matrix, int dimension, decimal[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.GetLength(0);
            int cols = matrix.GetLength(1);

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    decimal s = 0;
                    for (int i = 0; i < rows; i++)
                        s = (decimal)(s + (decimal)matrix[i, j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    decimal s = 0;
                    for (int i = 0; i < cols; i++)
                        s = (decimal)(s + (decimal)matrix[j, i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static decimal[] Product(this float[][] matrix, int dimension, decimal[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.Length;
            int cols = matrix[0].Length;

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    decimal s = 1;
                    for (int i = 0; i < rows; i++)
                        s = (decimal)(s * (decimal)matrix[i][j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    decimal s = 1;
                    for (int i = 0; i < cols; i++)
                        s = (decimal)(s * (decimal)matrix[j][i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static decimal[] Product(this float[,] matrix, int dimension, decimal[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.GetLength(0);
            int cols = matrix.GetLength(1);

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    decimal s = 1;
                    for (int i = 0; i < rows; i++)
                        s = (decimal)(s * (decimal)matrix[i, j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    decimal s = 1;
                    for (int i = 0; i < cols; i++)
                        s = (decimal)(s * (decimal)matrix[j, i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static int[] Sum(this double[][] matrix, int dimension, int[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.Length;
            int cols = matrix[0].Length;

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    int s = 0;
                    for (int i = 0; i < rows; i++)
                        s = (int)(s + (int)matrix[i][j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    int s = 0;
                    for (int i = 0; i < cols; i++)
                        s = (int)(s + (int)matrix[j][i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static int[] Sum(this double[,] matrix, int dimension, int[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.GetLength(0);
            int cols = matrix.GetLength(1);

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    int s = 0;
                    for (int i = 0; i < rows; i++)
                        s = (int)(s + (int)matrix[i, j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    int s = 0;
                    for (int i = 0; i < cols; i++)
                        s = (int)(s + (int)matrix[j, i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static int[] Product(this double[][] matrix, int dimension, int[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.Length;
            int cols = matrix[0].Length;

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    int s = 1;
                    for (int i = 0; i < rows; i++)
                        s = (int)(s * (int)matrix[i][j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    int s = 1;
                    for (int i = 0; i < cols; i++)
                        s = (int)(s * (int)matrix[j][i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static int[] Product(this double[,] matrix, int dimension, int[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.GetLength(0);
            int cols = matrix.GetLength(1);

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    int s = 1;
                    for (int i = 0; i < rows; i++)
                        s = (int)(s * (int)matrix[i, j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    int s = 1;
                    for (int i = 0; i < cols; i++)
                        s = (int)(s * (int)matrix[j, i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static short[] Sum(this double[][] matrix, int dimension, short[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.Length;
            int cols = matrix[0].Length;

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    short s = 0;
                    for (int i = 0; i < rows; i++)
                        s = (short)(s + (short)matrix[i][j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    short s = 0;
                    for (int i = 0; i < cols; i++)
                        s = (short)(s + (short)matrix[j][i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static short[] Sum(this double[,] matrix, int dimension, short[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.GetLength(0);
            int cols = matrix.GetLength(1);

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    short s = 0;
                    for (int i = 0; i < rows; i++)
                        s = (short)(s + (short)matrix[i, j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    short s = 0;
                    for (int i = 0; i < cols; i++)
                        s = (short)(s + (short)matrix[j, i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static short[] Product(this double[][] matrix, int dimension, short[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.Length;
            int cols = matrix[0].Length;

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    short s = 1;
                    for (int i = 0; i < rows; i++)
                        s = (short)(s * (short)matrix[i][j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    short s = 1;
                    for (int i = 0; i < cols; i++)
                        s = (short)(s * (short)matrix[j][i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static short[] Product(this double[,] matrix, int dimension, short[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.GetLength(0);
            int cols = matrix.GetLength(1);

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    short s = 1;
                    for (int i = 0; i < rows; i++)
                        s = (short)(s * (short)matrix[i, j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    short s = 1;
                    for (int i = 0; i < cols; i++)
                        s = (short)(s * (short)matrix[j, i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static float[] Sum(this double[][] matrix, int dimension, float[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.Length;
            int cols = matrix[0].Length;

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    float s = 0;
                    for (int i = 0; i < rows; i++)
                        s = (float)(s + (float)matrix[i][j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    float s = 0;
                    for (int i = 0; i < cols; i++)
                        s = (float)(s + (float)matrix[j][i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static float[] Sum(this double[,] matrix, int dimension, float[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.GetLength(0);
            int cols = matrix.GetLength(1);

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    float s = 0;
                    for (int i = 0; i < rows; i++)
                        s = (float)(s + (float)matrix[i, j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    float s = 0;
                    for (int i = 0; i < cols; i++)
                        s = (float)(s + (float)matrix[j, i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static float[] Product(this double[][] matrix, int dimension, float[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.Length;
            int cols = matrix[0].Length;

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    float s = 1;
                    for (int i = 0; i < rows; i++)
                        s = (float)(s * (float)matrix[i][j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    float s = 1;
                    for (int i = 0; i < cols; i++)
                        s = (float)(s * (float)matrix[j][i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static float[] Product(this double[,] matrix, int dimension, float[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.GetLength(0);
            int cols = matrix.GetLength(1);

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    float s = 1;
                    for (int i = 0; i < rows; i++)
                        s = (float)(s * (float)matrix[i, j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    float s = 1;
                    for (int i = 0; i < cols; i++)
                        s = (float)(s * (float)matrix[j, i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static double[] Sum(this double[][] matrix, int dimension, double[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.Length;
            int cols = matrix[0].Length;

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    double s = 0;
                    for (int i = 0; i < rows; i++)
                        s = (double)(s + (double)matrix[i][j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    double s = 0;
                    for (int i = 0; i < cols; i++)
                        s = (double)(s + (double)matrix[j][i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static double[] Sum(this double[,] matrix, int dimension, double[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.GetLength(0);
            int cols = matrix.GetLength(1);

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    double s = 0;
                    for (int i = 0; i < rows; i++)
                        s = (double)(s + (double)matrix[i, j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    double s = 0;
                    for (int i = 0; i < cols; i++)
                        s = (double)(s + (double)matrix[j, i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static double[] Product(this double[][] matrix, int dimension, double[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.Length;
            int cols = matrix[0].Length;

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    double s = 1;
                    for (int i = 0; i < rows; i++)
                        s = (double)(s * (double)matrix[i][j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    double s = 1;
                    for (int i = 0; i < cols; i++)
                        s = (double)(s * (double)matrix[j][i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static double[] Product(this double[,] matrix, int dimension, double[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.GetLength(0);
            int cols = matrix.GetLength(1);

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    double s = 1;
                    for (int i = 0; i < rows; i++)
                        s = (double)(s * (double)matrix[i, j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    double s = 1;
                    for (int i = 0; i < cols; i++)
                        s = (double)(s * (double)matrix[j, i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static long[] Sum(this double[][] matrix, int dimension, long[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.Length;
            int cols = matrix[0].Length;

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    long s = 0;
                    for (int i = 0; i < rows; i++)
                        s = (long)(s + (long)matrix[i][j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    long s = 0;
                    for (int i = 0; i < cols; i++)
                        s = (long)(s + (long)matrix[j][i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static long[] Sum(this double[,] matrix, int dimension, long[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.GetLength(0);
            int cols = matrix.GetLength(1);

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    long s = 0;
                    for (int i = 0; i < rows; i++)
                        s = (long)(s + (long)matrix[i, j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    long s = 0;
                    for (int i = 0; i < cols; i++)
                        s = (long)(s + (long)matrix[j, i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static long[] Product(this double[][] matrix, int dimension, long[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.Length;
            int cols = matrix[0].Length;

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    long s = 1;
                    for (int i = 0; i < rows; i++)
                        s = (long)(s * (long)matrix[i][j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    long s = 1;
                    for (int i = 0; i < cols; i++)
                        s = (long)(s * (long)matrix[j][i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static long[] Product(this double[,] matrix, int dimension, long[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.GetLength(0);
            int cols = matrix.GetLength(1);

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    long s = 1;
                    for (int i = 0; i < rows; i++)
                        s = (long)(s * (long)matrix[i, j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    long s = 1;
                    for (int i = 0; i < cols; i++)
                        s = (long)(s * (long)matrix[j, i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static decimal[] Sum(this double[][] matrix, int dimension, decimal[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.Length;
            int cols = matrix[0].Length;

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    decimal s = 0;
                    for (int i = 0; i < rows; i++)
                        s = (decimal)(s + (decimal)matrix[i][j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    decimal s = 0;
                    for (int i = 0; i < cols; i++)
                        s = (decimal)(s + (decimal)matrix[j][i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static decimal[] Sum(this double[,] matrix, int dimension, decimal[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.GetLength(0);
            int cols = matrix.GetLength(1);

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    decimal s = 0;
                    for (int i = 0; i < rows; i++)
                        s = (decimal)(s + (decimal)matrix[i, j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    decimal s = 0;
                    for (int i = 0; i < cols; i++)
                        s = (decimal)(s + (decimal)matrix[j, i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static decimal[] Product(this double[][] matrix, int dimension, decimal[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.Length;
            int cols = matrix[0].Length;

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    decimal s = 1;
                    for (int i = 0; i < rows; i++)
                        s = (decimal)(s * (decimal)matrix[i][j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    decimal s = 1;
                    for (int i = 0; i < cols; i++)
                        s = (decimal)(s * (decimal)matrix[j][i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static decimal[] Product(this double[,] matrix, int dimension, decimal[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.GetLength(0);
            int cols = matrix.GetLength(1);

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    decimal s = 1;
                    for (int i = 0; i < rows; i++)
                        s = (decimal)(s * (decimal)matrix[i, j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    decimal s = 1;
                    for (int i = 0; i < cols; i++)
                        s = (decimal)(s * (decimal)matrix[j, i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static int[] Sum(this long[][] matrix, int dimension, int[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.Length;
            int cols = matrix[0].Length;

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    int s = 0;
                    for (int i = 0; i < rows; i++)
                        s = (int)(s + (int)matrix[i][j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    int s = 0;
                    for (int i = 0; i < cols; i++)
                        s = (int)(s + (int)matrix[j][i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static int[] Sum(this long[,] matrix, int dimension, int[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.GetLength(0);
            int cols = matrix.GetLength(1);

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    int s = 0;
                    for (int i = 0; i < rows; i++)
                        s = (int)(s + (int)matrix[i, j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    int s = 0;
                    for (int i = 0; i < cols; i++)
                        s = (int)(s + (int)matrix[j, i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static int[] Product(this long[][] matrix, int dimension, int[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.Length;
            int cols = matrix[0].Length;

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    int s = 1;
                    for (int i = 0; i < rows; i++)
                        s = (int)(s * (int)matrix[i][j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    int s = 1;
                    for (int i = 0; i < cols; i++)
                        s = (int)(s * (int)matrix[j][i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static int[] Product(this long[,] matrix, int dimension, int[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.GetLength(0);
            int cols = matrix.GetLength(1);

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    int s = 1;
                    for (int i = 0; i < rows; i++)
                        s = (int)(s * (int)matrix[i, j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    int s = 1;
                    for (int i = 0; i < cols; i++)
                        s = (int)(s * (int)matrix[j, i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static short[] Sum(this long[][] matrix, int dimension, short[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.Length;
            int cols = matrix[0].Length;

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    short s = 0;
                    for (int i = 0; i < rows; i++)
                        s = (short)(s + (short)matrix[i][j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    short s = 0;
                    for (int i = 0; i < cols; i++)
                        s = (short)(s + (short)matrix[j][i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static short[] Sum(this long[,] matrix, int dimension, short[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.GetLength(0);
            int cols = matrix.GetLength(1);

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    short s = 0;
                    for (int i = 0; i < rows; i++)
                        s = (short)(s + (short)matrix[i, j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    short s = 0;
                    for (int i = 0; i < cols; i++)
                        s = (short)(s + (short)matrix[j, i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static short[] Product(this long[][] matrix, int dimension, short[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.Length;
            int cols = matrix[0].Length;

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    short s = 1;
                    for (int i = 0; i < rows; i++)
                        s = (short)(s * (short)matrix[i][j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    short s = 1;
                    for (int i = 0; i < cols; i++)
                        s = (short)(s * (short)matrix[j][i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static short[] Product(this long[,] matrix, int dimension, short[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.GetLength(0);
            int cols = matrix.GetLength(1);

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    short s = 1;
                    for (int i = 0; i < rows; i++)
                        s = (short)(s * (short)matrix[i, j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    short s = 1;
                    for (int i = 0; i < cols; i++)
                        s = (short)(s * (short)matrix[j, i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static float[] Sum(this long[][] matrix, int dimension, float[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.Length;
            int cols = matrix[0].Length;

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    float s = 0;
                    for (int i = 0; i < rows; i++)
                        s = (float)(s + (float)matrix[i][j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    float s = 0;
                    for (int i = 0; i < cols; i++)
                        s = (float)(s + (float)matrix[j][i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static float[] Sum(this long[,] matrix, int dimension, float[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.GetLength(0);
            int cols = matrix.GetLength(1);

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    float s = 0;
                    for (int i = 0; i < rows; i++)
                        s = (float)(s + (float)matrix[i, j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    float s = 0;
                    for (int i = 0; i < cols; i++)
                        s = (float)(s + (float)matrix[j, i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static float[] Product(this long[][] matrix, int dimension, float[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.Length;
            int cols = matrix[0].Length;

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    float s = 1;
                    for (int i = 0; i < rows; i++)
                        s = (float)(s * (float)matrix[i][j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    float s = 1;
                    for (int i = 0; i < cols; i++)
                        s = (float)(s * (float)matrix[j][i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static float[] Product(this long[,] matrix, int dimension, float[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.GetLength(0);
            int cols = matrix.GetLength(1);

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    float s = 1;
                    for (int i = 0; i < rows; i++)
                        s = (float)(s * (float)matrix[i, j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    float s = 1;
                    for (int i = 0; i < cols; i++)
                        s = (float)(s * (float)matrix[j, i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static double[] Sum(this long[][] matrix, int dimension, double[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.Length;
            int cols = matrix[0].Length;

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    double s = 0;
                    for (int i = 0; i < rows; i++)
                        s = (double)(s + (double)matrix[i][j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    double s = 0;
                    for (int i = 0; i < cols; i++)
                        s = (double)(s + (double)matrix[j][i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static double[] Sum(this long[,] matrix, int dimension, double[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.GetLength(0);
            int cols = matrix.GetLength(1);

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    double s = 0;
                    for (int i = 0; i < rows; i++)
                        s = (double)(s + (double)matrix[i, j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    double s = 0;
                    for (int i = 0; i < cols; i++)
                        s = (double)(s + (double)matrix[j, i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static double[] Product(this long[][] matrix, int dimension, double[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.Length;
            int cols = matrix[0].Length;

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    double s = 1;
                    for (int i = 0; i < rows; i++)
                        s = (double)(s * (double)matrix[i][j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    double s = 1;
                    for (int i = 0; i < cols; i++)
                        s = (double)(s * (double)matrix[j][i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static double[] Product(this long[,] matrix, int dimension, double[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.GetLength(0);
            int cols = matrix.GetLength(1);

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    double s = 1;
                    for (int i = 0; i < rows; i++)
                        s = (double)(s * (double)matrix[i, j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    double s = 1;
                    for (int i = 0; i < cols; i++)
                        s = (double)(s * (double)matrix[j, i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static long[] Sum(this long[][] matrix, int dimension, long[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.Length;
            int cols = matrix[0].Length;

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    long s = 0;
                    for (int i = 0; i < rows; i++)
                        s = (long)(s + (long)matrix[i][j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    long s = 0;
                    for (int i = 0; i < cols; i++)
                        s = (long)(s + (long)matrix[j][i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static long[] Sum(this long[,] matrix, int dimension, long[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.GetLength(0);
            int cols = matrix.GetLength(1);

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    long s = 0;
                    for (int i = 0; i < rows; i++)
                        s = (long)(s + (long)matrix[i, j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    long s = 0;
                    for (int i = 0; i < cols; i++)
                        s = (long)(s + (long)matrix[j, i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static long[] Product(this long[][] matrix, int dimension, long[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.Length;
            int cols = matrix[0].Length;

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    long s = 1;
                    for (int i = 0; i < rows; i++)
                        s = (long)(s * (long)matrix[i][j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    long s = 1;
                    for (int i = 0; i < cols; i++)
                        s = (long)(s * (long)matrix[j][i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static long[] Product(this long[,] matrix, int dimension, long[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.GetLength(0);
            int cols = matrix.GetLength(1);

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    long s = 1;
                    for (int i = 0; i < rows; i++)
                        s = (long)(s * (long)matrix[i, j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    long s = 1;
                    for (int i = 0; i < cols; i++)
                        s = (long)(s * (long)matrix[j, i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static decimal[] Sum(this long[][] matrix, int dimension, decimal[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.Length;
            int cols = matrix[0].Length;

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    decimal s = 0;
                    for (int i = 0; i < rows; i++)
                        s = (decimal)(s + (decimal)matrix[i][j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    decimal s = 0;
                    for (int i = 0; i < cols; i++)
                        s = (decimal)(s + (decimal)matrix[j][i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static decimal[] Sum(this long[,] matrix, int dimension, decimal[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.GetLength(0);
            int cols = matrix.GetLength(1);

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    decimal s = 0;
                    for (int i = 0; i < rows; i++)
                        s = (decimal)(s + (decimal)matrix[i, j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    decimal s = 0;
                    for (int i = 0; i < cols; i++)
                        s = (decimal)(s + (decimal)matrix[j, i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static decimal[] Product(this long[][] matrix, int dimension, decimal[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.Length;
            int cols = matrix[0].Length;

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    decimal s = 1;
                    for (int i = 0; i < rows; i++)
                        s = (decimal)(s * (decimal)matrix[i][j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    decimal s = 1;
                    for (int i = 0; i < cols; i++)
                        s = (decimal)(s * (decimal)matrix[j][i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static decimal[] Product(this long[,] matrix, int dimension, decimal[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.GetLength(0);
            int cols = matrix.GetLength(1);

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    decimal s = 1;
                    for (int i = 0; i < rows; i++)
                        s = (decimal)(s * (decimal)matrix[i, j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    decimal s = 1;
                    for (int i = 0; i < cols; i++)
                        s = (decimal)(s * (decimal)matrix[j, i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static int[] Sum(this decimal[][] matrix, int dimension, int[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.Length;
            int cols = matrix[0].Length;

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    int s = 0;
                    for (int i = 0; i < rows; i++)
                        s = (int)(s + (int)matrix[i][j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    int s = 0;
                    for (int i = 0; i < cols; i++)
                        s = (int)(s + (int)matrix[j][i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static int[] Sum(this decimal[,] matrix, int dimension, int[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.GetLength(0);
            int cols = matrix.GetLength(1);

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    int s = 0;
                    for (int i = 0; i < rows; i++)
                        s = (int)(s + (int)matrix[i, j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    int s = 0;
                    for (int i = 0; i < cols; i++)
                        s = (int)(s + (int)matrix[j, i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static int[] Product(this decimal[][] matrix, int dimension, int[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.Length;
            int cols = matrix[0].Length;

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    int s = 1;
                    for (int i = 0; i < rows; i++)
                        s = (int)(s * (int)matrix[i][j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    int s = 1;
                    for (int i = 0; i < cols; i++)
                        s = (int)(s * (int)matrix[j][i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static int[] Product(this decimal[,] matrix, int dimension, int[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.GetLength(0);
            int cols = matrix.GetLength(1);

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    int s = 1;
                    for (int i = 0; i < rows; i++)
                        s = (int)(s * (int)matrix[i, j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    int s = 1;
                    for (int i = 0; i < cols; i++)
                        s = (int)(s * (int)matrix[j, i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static short[] Sum(this decimal[][] matrix, int dimension, short[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.Length;
            int cols = matrix[0].Length;

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    short s = 0;
                    for (int i = 0; i < rows; i++)
                        s = (short)(s + (short)matrix[i][j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    short s = 0;
                    for (int i = 0; i < cols; i++)
                        s = (short)(s + (short)matrix[j][i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static short[] Sum(this decimal[,] matrix, int dimension, short[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.GetLength(0);
            int cols = matrix.GetLength(1);

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    short s = 0;
                    for (int i = 0; i < rows; i++)
                        s = (short)(s + (short)matrix[i, j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    short s = 0;
                    for (int i = 0; i < cols; i++)
                        s = (short)(s + (short)matrix[j, i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static short[] Product(this decimal[][] matrix, int dimension, short[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.Length;
            int cols = matrix[0].Length;

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    short s = 1;
                    for (int i = 0; i < rows; i++)
                        s = (short)(s * (short)matrix[i][j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    short s = 1;
                    for (int i = 0; i < cols; i++)
                        s = (short)(s * (short)matrix[j][i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static short[] Product(this decimal[,] matrix, int dimension, short[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.GetLength(0);
            int cols = matrix.GetLength(1);

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    short s = 1;
                    for (int i = 0; i < rows; i++)
                        s = (short)(s * (short)matrix[i, j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    short s = 1;
                    for (int i = 0; i < cols; i++)
                        s = (short)(s * (short)matrix[j, i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static float[] Sum(this decimal[][] matrix, int dimension, float[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.Length;
            int cols = matrix[0].Length;

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    float s = 0;
                    for (int i = 0; i < rows; i++)
                        s = (float)(s + (float)matrix[i][j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    float s = 0;
                    for (int i = 0; i < cols; i++)
                        s = (float)(s + (float)matrix[j][i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static float[] Sum(this decimal[,] matrix, int dimension, float[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.GetLength(0);
            int cols = matrix.GetLength(1);

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    float s = 0;
                    for (int i = 0; i < rows; i++)
                        s = (float)(s + (float)matrix[i, j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    float s = 0;
                    for (int i = 0; i < cols; i++)
                        s = (float)(s + (float)matrix[j, i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static float[] Product(this decimal[][] matrix, int dimension, float[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.Length;
            int cols = matrix[0].Length;

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    float s = 1;
                    for (int i = 0; i < rows; i++)
                        s = (float)(s * (float)matrix[i][j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    float s = 1;
                    for (int i = 0; i < cols; i++)
                        s = (float)(s * (float)matrix[j][i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static float[] Product(this decimal[,] matrix, int dimension, float[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.GetLength(0);
            int cols = matrix.GetLength(1);

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    float s = 1;
                    for (int i = 0; i < rows; i++)
                        s = (float)(s * (float)matrix[i, j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    float s = 1;
                    for (int i = 0; i < cols; i++)
                        s = (float)(s * (float)matrix[j, i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static double[] Sum(this decimal[][] matrix, int dimension, double[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.Length;
            int cols = matrix[0].Length;

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    double s = 0;
                    for (int i = 0; i < rows; i++)
                        s = (double)(s + (double)matrix[i][j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    double s = 0;
                    for (int i = 0; i < cols; i++)
                        s = (double)(s + (double)matrix[j][i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static double[] Sum(this decimal[,] matrix, int dimension, double[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.GetLength(0);
            int cols = matrix.GetLength(1);

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    double s = 0;
                    for (int i = 0; i < rows; i++)
                        s = (double)(s + (double)matrix[i, j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    double s = 0;
                    for (int i = 0; i < cols; i++)
                        s = (double)(s + (double)matrix[j, i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static double[] Product(this decimal[][] matrix, int dimension, double[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.Length;
            int cols = matrix[0].Length;

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    double s = 1;
                    for (int i = 0; i < rows; i++)
                        s = (double)(s * (double)matrix[i][j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    double s = 1;
                    for (int i = 0; i < cols; i++)
                        s = (double)(s * (double)matrix[j][i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static double[] Product(this decimal[,] matrix, int dimension, double[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.GetLength(0);
            int cols = matrix.GetLength(1);

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    double s = 1;
                    for (int i = 0; i < rows; i++)
                        s = (double)(s * (double)matrix[i, j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    double s = 1;
                    for (int i = 0; i < cols; i++)
                        s = (double)(s * (double)matrix[j, i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static long[] Sum(this decimal[][] matrix, int dimension, long[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.Length;
            int cols = matrix[0].Length;

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    long s = 0;
                    for (int i = 0; i < rows; i++)
                        s = (long)(s + (long)matrix[i][j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    long s = 0;
                    for (int i = 0; i < cols; i++)
                        s = (long)(s + (long)matrix[j][i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static long[] Sum(this decimal[,] matrix, int dimension, long[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.GetLength(0);
            int cols = matrix.GetLength(1);

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    long s = 0;
                    for (int i = 0; i < rows; i++)
                        s = (long)(s + (long)matrix[i, j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    long s = 0;
                    for (int i = 0; i < cols; i++)
                        s = (long)(s + (long)matrix[j, i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static long[] Product(this decimal[][] matrix, int dimension, long[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.Length;
            int cols = matrix[0].Length;

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    long s = 1;
                    for (int i = 0; i < rows; i++)
                        s = (long)(s * (long)matrix[i][j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    long s = 1;
                    for (int i = 0; i < cols; i++)
                        s = (long)(s * (long)matrix[j][i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static long[] Product(this decimal[,] matrix, int dimension, long[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.GetLength(0);
            int cols = matrix.GetLength(1);

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    long s = 1;
                    for (int i = 0; i < rows; i++)
                        s = (long)(s * (long)matrix[i, j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    long s = 1;
                    for (int i = 0; i < cols; i++)
                        s = (long)(s * (long)matrix[j, i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static decimal[] Sum(this decimal[][] matrix, int dimension, decimal[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.Length;
            int cols = matrix[0].Length;

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    decimal s = 0;
                    for (int i = 0; i < rows; i++)
                        s = (decimal)(s + (decimal)matrix[i][j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    decimal s = 0;
                    for (int i = 0; i < cols; i++)
                        s = (decimal)(s + (decimal)matrix[j][i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static decimal[] Sum(this decimal[,] matrix, int dimension, decimal[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.GetLength(0);
            int cols = matrix.GetLength(1);

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    decimal s = 0;
                    for (int i = 0; i < rows; i++)
                        s = (decimal)(s + (decimal)matrix[i, j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    decimal s = 0;
                    for (int i = 0; i < cols; i++)
                        s = (decimal)(s + (decimal)matrix[j, i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static decimal[] Product(this decimal[][] matrix, int dimension, decimal[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.Length;
            int cols = matrix[0].Length;

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    decimal s = 1;
                    for (int i = 0; i < rows; i++)
                        s = (decimal)(s * (decimal)matrix[i][j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    decimal s = 1;
                    for (int i = 0; i < cols; i++)
                        s = (decimal)(s * (decimal)matrix[j][i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static decimal[] Product(this decimal[,] matrix, int dimension, decimal[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.GetLength(0);
            int cols = matrix.GetLength(1);

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    decimal s = 1;
                    for (int i = 0; i < rows; i++)
                        s = (decimal)(s * (decimal)matrix[i, j]);
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    decimal s = 1;
                    for (int i = 0; i < cols; i++)
                        s = (decimal)(s * (decimal)matrix[j, i]);
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static int[] Sum(this bool[][] matrix, int dimension, int[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.Length;
            int cols = matrix[0].Length;

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    int s = 0;
                    for (int i = 0; i < rows; i++)
                        s = (int)(s + (matrix[i][j] ? 1 : 0));
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    int s = 0;
                    for (int i = 0; i < cols; i++)
                        s = (int)(s + (matrix[j][i] ? 1 : 0));
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static int[] Sum(this bool[,] matrix, int dimension, int[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.GetLength(0);
            int cols = matrix.GetLength(1);

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    int s = 0;
                    for (int i = 0; i < rows; i++)
                        s = (int)(s + (matrix[i, j] ? 1 : 0));
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    int s = 0;
                    for (int i = 0; i < cols; i++)
                        s = (int)(s + (matrix[j, i] ? 1 : 0));
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static int[] Product(this bool[][] matrix, int dimension, int[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.Length;
            int cols = matrix[0].Length;

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    int s = 1;
                    for (int i = 0; i < rows; i++)
                        s = (int)(s * (matrix[i][j] ? 1 : 0));
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    int s = 1;
                    for (int i = 0; i < cols; i++)
                        s = (int)(s * (matrix[j][i] ? 1 : 0));
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static int[] Product(this bool[,] matrix, int dimension, int[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.GetLength(0);
            int cols = matrix.GetLength(1);

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    int s = 1;
                    for (int i = 0; i < rows; i++)
                        s = (int)(s * (matrix[i, j] ? 1 : 0));
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    int s = 1;
                    for (int i = 0; i < cols; i++)
                        s = (int)(s * (matrix[j, i] ? 1 : 0));
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static short[] Sum(this bool[][] matrix, int dimension, short[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.Length;
            int cols = matrix[0].Length;

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    short s = 0;
                    for (int i = 0; i < rows; i++)
                        s = (short)(s + (matrix[i][j] ? 1 : 0));
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    short s = 0;
                    for (int i = 0; i < cols; i++)
                        s = (short)(s + (matrix[j][i] ? 1 : 0));
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static short[] Sum(this bool[,] matrix, int dimension, short[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.GetLength(0);
            int cols = matrix.GetLength(1);

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    short s = 0;
                    for (int i = 0; i < rows; i++)
                        s = (short)(s + (matrix[i, j] ? 1 : 0));
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    short s = 0;
                    for (int i = 0; i < cols; i++)
                        s = (short)(s + (matrix[j, i] ? 1 : 0));
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static short[] Product(this bool[][] matrix, int dimension, short[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.Length;
            int cols = matrix[0].Length;

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    short s = 1;
                    for (int i = 0; i < rows; i++)
                        s = (short)(s * (matrix[i][j] ? 1 : 0));
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    short s = 1;
                    for (int i = 0; i < cols; i++)
                        s = (short)(s * (matrix[j][i] ? 1 : 0));
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static short[] Product(this bool[,] matrix, int dimension, short[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.GetLength(0);
            int cols = matrix.GetLength(1);

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    short s = 1;
                    for (int i = 0; i < rows; i++)
                        s = (short)(s * (matrix[i, j] ? 1 : 0));
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    short s = 1;
                    for (int i = 0; i < cols; i++)
                        s = (short)(s * (matrix[j, i] ? 1 : 0));
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static float[] Sum(this bool[][] matrix, int dimension, float[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.Length;
            int cols = matrix[0].Length;

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    float s = 0;
                    for (int i = 0; i < rows; i++)
                        s = (float)(s + (matrix[i][j] ? 1 : 0));
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    float s = 0;
                    for (int i = 0; i < cols; i++)
                        s = (float)(s + (matrix[j][i] ? 1 : 0));
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static float[] Sum(this bool[,] matrix, int dimension, float[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.GetLength(0);
            int cols = matrix.GetLength(1);

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    float s = 0;
                    for (int i = 0; i < rows; i++)
                        s = (float)(s + (matrix[i, j] ? 1 : 0));
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    float s = 0;
                    for (int i = 0; i < cols; i++)
                        s = (float)(s + (matrix[j, i] ? 1 : 0));
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static float[] Product(this bool[][] matrix, int dimension, float[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.Length;
            int cols = matrix[0].Length;

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    float s = 1;
                    for (int i = 0; i < rows; i++)
                        s = (float)(s * (matrix[i][j] ? 1 : 0));
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    float s = 1;
                    for (int i = 0; i < cols; i++)
                        s = (float)(s * (matrix[j][i] ? 1 : 0));
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static float[] Product(this bool[,] matrix, int dimension, float[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.GetLength(0);
            int cols = matrix.GetLength(1);

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    float s = 1;
                    for (int i = 0; i < rows; i++)
                        s = (float)(s * (matrix[i, j] ? 1 : 0));
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    float s = 1;
                    for (int i = 0; i < cols; i++)
                        s = (float)(s * (matrix[j, i] ? 1 : 0));
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static double[] Sum(this bool[][] matrix, int dimension, double[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.Length;
            int cols = matrix[0].Length;

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    double s = 0;
                    for (int i = 0; i < rows; i++)
                        s = (double)(s + (matrix[i][j] ? 1 : 0));
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    double s = 0;
                    for (int i = 0; i < cols; i++)
                        s = (double)(s + (matrix[j][i] ? 1 : 0));
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static double[] Sum(this bool[,] matrix, int dimension, double[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.GetLength(0);
            int cols = matrix.GetLength(1);

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    double s = 0;
                    for (int i = 0; i < rows; i++)
                        s = (double)(s + (matrix[i, j] ? 1 : 0));
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    double s = 0;
                    for (int i = 0; i < cols; i++)
                        s = (double)(s + (matrix[j, i] ? 1 : 0));
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static double[] Product(this bool[][] matrix, int dimension, double[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.Length;
            int cols = matrix[0].Length;

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    double s = 1;
                    for (int i = 0; i < rows; i++)
                        s = (double)(s * (matrix[i][j] ? 1 : 0));
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    double s = 1;
                    for (int i = 0; i < cols; i++)
                        s = (double)(s * (matrix[j][i] ? 1 : 0));
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static double[] Product(this bool[,] matrix, int dimension, double[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.GetLength(0);
            int cols = matrix.GetLength(1);

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    double s = 1;
                    for (int i = 0; i < rows; i++)
                        s = (double)(s * (matrix[i, j] ? 1 : 0));
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    double s = 1;
                    for (int i = 0; i < cols; i++)
                        s = (double)(s * (matrix[j, i] ? 1 : 0));
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static long[] Sum(this bool[][] matrix, int dimension, long[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.Length;
            int cols = matrix[0].Length;

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    long s = 0;
                    for (int i = 0; i < rows; i++)
                        s = (long)(s + (matrix[i][j] ? 1 : 0));
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    long s = 0;
                    for (int i = 0; i < cols; i++)
                        s = (long)(s + (matrix[j][i] ? 1 : 0));
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static long[] Sum(this bool[,] matrix, int dimension, long[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.GetLength(0);
            int cols = matrix.GetLength(1);

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    long s = 0;
                    for (int i = 0; i < rows; i++)
                        s = (long)(s + (matrix[i, j] ? 1 : 0));
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    long s = 0;
                    for (int i = 0; i < cols; i++)
                        s = (long)(s + (matrix[j, i] ? 1 : 0));
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static long[] Product(this bool[][] matrix, int dimension, long[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.Length;
            int cols = matrix[0].Length;

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    long s = 1;
                    for (int i = 0; i < rows; i++)
                        s = (long)(s * (matrix[i][j] ? 1 : 0));
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    long s = 1;
                    for (int i = 0; i < cols; i++)
                        s = (long)(s * (matrix[j][i] ? 1 : 0));
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static long[] Product(this bool[,] matrix, int dimension, long[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.GetLength(0);
            int cols = matrix.GetLength(1);

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    long s = 1;
                    for (int i = 0; i < rows; i++)
                        s = (long)(s * (matrix[i, j] ? 1 : 0));
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    long s = 1;
                    for (int i = 0; i < cols; i++)
                        s = (long)(s * (matrix[j, i] ? 1 : 0));
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static decimal[] Sum(this bool[][] matrix, int dimension, decimal[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.Length;
            int cols = matrix[0].Length;

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    decimal s = 0;
                    for (int i = 0; i < rows; i++)
                        s = (decimal)(s + (matrix[i][j] ? 1 : 0));
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    decimal s = 0;
                    for (int i = 0; i < cols; i++)
                        s = (decimal)(s + (matrix[j][i] ? 1 : 0));
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the sum will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static decimal[] Sum(this bool[,] matrix, int dimension, decimal[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.GetLength(0);
            int cols = matrix.GetLength(1);

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    decimal s = 0;
                    for (int i = 0; i < rows; i++)
                        s = (decimal)(s + (matrix[i, j] ? 1 : 0));
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    decimal s = 0;
                    for (int i = 0; i < cols; i++)
                        s = (decimal)(s + (matrix[j, i] ? 1 : 0));
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static decimal[] Product(this bool[][] matrix, int dimension, decimal[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.Length;
            int cols = matrix[0].Length;

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    decimal s = 1;
                    for (int i = 0; i < rows; i++)
                        s = (decimal)(s * (matrix[i][j] ? 1 : 0));
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    decimal s = 1;
                    for (int i = 0; i < cols; i++)
                        s = (decimal)(s * (matrix[j][i] ? 1 : 0));
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix product.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose product will be calculated.</param>
        /// <param name="dimension">The dimension in which the product will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static decimal[] Product(this bool[,] matrix, int dimension, decimal[] result)
        {
            if (matrix == null) 
                throw new ArgumentNullException("matrix");

            int rows = matrix.GetLength(0);
            int cols = matrix.GetLength(1);

            if (dimension == 0)
            {
                for (int j = 0; j < cols; j++)
                {
                    decimal s = 1;
                    for (int i = 0; i < rows; i++)
                        s = (decimal)(s * (matrix[i, j] ? 1 : 0));
                    result[j] = s;
                }
            }
            else if (dimension == 1)
            {
                for (int j = 0; j < rows; j++)
                {
                    decimal s = 1;
                    for (int i = 0; i < cols; i++)
                        s = (decimal)(s * (matrix[j, i] ? 1 : 0));
                    result[j] = s;
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }


        /// <summary>
        ///   Matrix cumulative sum.
        /// </summary>
        ///
        /// <param name="vector">A vector whose cumulative sum will be calculated.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static int[] CumulativeSum(this int[] vector)
        {
            if (vector.Length == 0)
                return new int[0];

            return CumulativeSum(vector, Accord.Math.Vector.CreateAs(vector));
        }

        /// <summary>
        ///   Matrix cumulative sum.
        /// </summary>
        ///
        /// <param name="vector">A vector whose cumulative sum will be calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static int[] CumulativeSum(this int[] vector, int[] result)
        {
            result[0] = vector[0];
            for (int i = 1; i < vector.Length; i++)
                result[i] = (int)(result[i - 1] + vector[i]);
            return result;
        }

        /// <summary>
        ///   Matrix cumulative sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose cumulative sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the cumulative will be
        ///   calculated.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static int[][] CumulativeSum(this int[][] matrix, int dimension)
        {
            int rows = matrix.Rows();
            int cols = matrix.Columns();
            if (dimension == 1)
                return CumulativeSum(matrix, dimension, Jagged.Zeros<int>(rows, cols));
            return CumulativeSum(matrix, dimension, Jagged.Zeros<int>(cols, rows));
        }        

        /// <summary>
        ///   Matrix cumulative sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose cumulative sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the cumulative will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static int[][] CumulativeSum(this int[][] matrix, int dimension, int[][] result)
        {
            int rows = matrix.Rows();
            int cols = matrix.Columns();

            if (dimension == 1)
            {
                matrix.GetRow(0, result: result[0]);
                for (int i = 1; i < rows; i++)
                    for (int j = 0; j < cols; j++)
                        result[i][j] = (int)(result[i - 1][j] + matrix[i][j]);
            }
            else if (dimension == 0)
            {
                matrix.GetColumn(0, result: result[0]);
                for (int i = 1; i < cols; i++)
                    for (int j = 0; j < rows; j++)
                        result[i][j] = (int)(result[i - 1][j] + matrix[j][i]);
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix cumulative sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose cumulative sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the cumulative will be
        ///   calculated.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static int[,] CumulativeSum(this int[,] matrix, int dimension)
        {
            int rows = matrix.Rows();
            int cols = matrix.Columns();
            if (dimension == 1)
                return CumulativeSum(matrix, dimension, Matrix.Zeros<int>(rows, cols));
            return CumulativeSum(matrix, dimension, Matrix.Zeros<int>(cols, rows)); 
        }        

        /// <summary>
        ///   Matrix cumulative sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose cumulative sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the cumulative will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static int[,] CumulativeSum(this int[,] matrix, int dimension, int[,] result)
        {
            int rows = matrix.Rows();
            int cols = matrix.Columns();

            if (dimension == 1)
            {
                result.SetColumn(0, matrix.GetRow(0));
                for (int i = 1; i < rows; i++)
                    for (int j = 0; j < cols; j++)
                        result[i, j] = (int)(result[i - 1, j] + matrix[i, j]);
            }
            else if (dimension == 0)
            {
                result.SetColumn(0, matrix.GetColumn(0));
                for (int i = 1; i < cols; i++)
                    for (int j = 0; j < rows; j++)
                        result[i, j] = (int)(result[i - 1, j] + matrix[j, i]);
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix cumulative sum.
        /// </summary>
        ///
        /// <param name="vector">A vector whose cumulative sum will be calculated.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static short[] CumulativeSum(this short[] vector)
        {
            if (vector.Length == 0)
                return new short[0];

            return CumulativeSum(vector, Accord.Math.Vector.CreateAs(vector));
        }

        /// <summary>
        ///   Matrix cumulative sum.
        /// </summary>
        ///
        /// <param name="vector">A vector whose cumulative sum will be calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static short[] CumulativeSum(this short[] vector, short[] result)
        {
            result[0] = vector[0];
            for (int i = 1; i < vector.Length; i++)
                result[i] = (short)(result[i - 1] + vector[i]);
            return result;
        }

        /// <summary>
        ///   Matrix cumulative sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose cumulative sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the cumulative will be
        ///   calculated.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static short[][] CumulativeSum(this short[][] matrix, int dimension)
        {
            int rows = matrix.Rows();
            int cols = matrix.Columns();
            if (dimension == 1)
                return CumulativeSum(matrix, dimension, Jagged.Zeros<short>(rows, cols));
            return CumulativeSum(matrix, dimension, Jagged.Zeros<short>(cols, rows));
        }        

        /// <summary>
        ///   Matrix cumulative sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose cumulative sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the cumulative will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static short[][] CumulativeSum(this short[][] matrix, int dimension, short[][] result)
        {
            int rows = matrix.Rows();
            int cols = matrix.Columns();

            if (dimension == 1)
            {
                matrix.GetRow(0, result: result[0]);
                for (int i = 1; i < rows; i++)
                    for (int j = 0; j < cols; j++)
                        result[i][j] = (short)(result[i - 1][j] + matrix[i][j]);
            }
            else if (dimension == 0)
            {
                matrix.GetColumn(0, result: result[0]);
                for (int i = 1; i < cols; i++)
                    for (int j = 0; j < rows; j++)
                        result[i][j] = (short)(result[i - 1][j] + matrix[j][i]);
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix cumulative sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose cumulative sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the cumulative will be
        ///   calculated.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static short[,] CumulativeSum(this short[,] matrix, int dimension)
        {
            int rows = matrix.Rows();
            int cols = matrix.Columns();
            if (dimension == 1)
                return CumulativeSum(matrix, dimension, Matrix.Zeros<short>(rows, cols));
            return CumulativeSum(matrix, dimension, Matrix.Zeros<short>(cols, rows)); 
        }        

        /// <summary>
        ///   Matrix cumulative sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose cumulative sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the cumulative will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static short[,] CumulativeSum(this short[,] matrix, int dimension, short[,] result)
        {
            int rows = matrix.Rows();
            int cols = matrix.Columns();

            if (dimension == 1)
            {
                result.SetColumn(0, matrix.GetRow(0));
                for (int i = 1; i < rows; i++)
                    for (int j = 0; j < cols; j++)
                        result[i, j] = (short)(result[i - 1, j] + matrix[i, j]);
            }
            else if (dimension == 0)
            {
                result.SetColumn(0, matrix.GetColumn(0));
                for (int i = 1; i < cols; i++)
                    for (int j = 0; j < rows; j++)
                        result[i, j] = (short)(result[i - 1, j] + matrix[j, i]);
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix cumulative sum.
        /// </summary>
        ///
        /// <param name="vector">A vector whose cumulative sum will be calculated.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static float[] CumulativeSum(this float[] vector)
        {
            if (vector.Length == 0)
                return new float[0];

            return CumulativeSum(vector, Accord.Math.Vector.CreateAs(vector));
        }

        /// <summary>
        ///   Matrix cumulative sum.
        /// </summary>
        ///
        /// <param name="vector">A vector whose cumulative sum will be calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static float[] CumulativeSum(this float[] vector, float[] result)
        {
            result[0] = vector[0];
            for (int i = 1; i < vector.Length; i++)
                result[i] = (float)(result[i - 1] + vector[i]);
            return result;
        }

        /// <summary>
        ///   Matrix cumulative sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose cumulative sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the cumulative will be
        ///   calculated.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static float[][] CumulativeSum(this float[][] matrix, int dimension)
        {
            int rows = matrix.Rows();
            int cols = matrix.Columns();
            if (dimension == 1)
                return CumulativeSum(matrix, dimension, Jagged.Zeros<float>(rows, cols));
            return CumulativeSum(matrix, dimension, Jagged.Zeros<float>(cols, rows));
        }        

        /// <summary>
        ///   Matrix cumulative sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose cumulative sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the cumulative will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static float[][] CumulativeSum(this float[][] matrix, int dimension, float[][] result)
        {
            int rows = matrix.Rows();
            int cols = matrix.Columns();

            if (dimension == 1)
            {
                matrix.GetRow(0, result: result[0]);
                for (int i = 1; i < rows; i++)
                    for (int j = 0; j < cols; j++)
                        result[i][j] = (float)(result[i - 1][j] + matrix[i][j]);
            }
            else if (dimension == 0)
            {
                matrix.GetColumn(0, result: result[0]);
                for (int i = 1; i < cols; i++)
                    for (int j = 0; j < rows; j++)
                        result[i][j] = (float)(result[i - 1][j] + matrix[j][i]);
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix cumulative sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose cumulative sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the cumulative will be
        ///   calculated.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static float[,] CumulativeSum(this float[,] matrix, int dimension)
        {
            int rows = matrix.Rows();
            int cols = matrix.Columns();
            if (dimension == 1)
                return CumulativeSum(matrix, dimension, Matrix.Zeros<float>(rows, cols));
            return CumulativeSum(matrix, dimension, Matrix.Zeros<float>(cols, rows)); 
        }        

        /// <summary>
        ///   Matrix cumulative sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose cumulative sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the cumulative will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static float[,] CumulativeSum(this float[,] matrix, int dimension, float[,] result)
        {
            int rows = matrix.Rows();
            int cols = matrix.Columns();

            if (dimension == 1)
            {
                result.SetColumn(0, matrix.GetRow(0));
                for (int i = 1; i < rows; i++)
                    for (int j = 0; j < cols; j++)
                        result[i, j] = (float)(result[i - 1, j] + matrix[i, j]);
            }
            else if (dimension == 0)
            {
                result.SetColumn(0, matrix.GetColumn(0));
                for (int i = 1; i < cols; i++)
                    for (int j = 0; j < rows; j++)
                        result[i, j] = (float)(result[i - 1, j] + matrix[j, i]);
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix cumulative sum.
        /// </summary>
        ///
        /// <param name="vector">A vector whose cumulative sum will be calculated.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static double[] CumulativeSum(this double[] vector)
        {
            if (vector.Length == 0)
                return new double[0];

            return CumulativeSum(vector, Accord.Math.Vector.CreateAs(vector));
        }

        /// <summary>
        ///   Matrix cumulative sum.
        /// </summary>
        ///
        /// <param name="vector">A vector whose cumulative sum will be calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static double[] CumulativeSum(this double[] vector, double[] result)
        {
            result[0] = vector[0];
            for (int i = 1; i < vector.Length; i++)
                result[i] = (double)(result[i - 1] + vector[i]);
            return result;
        }

        /// <summary>
        ///   Matrix cumulative sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose cumulative sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the cumulative will be
        ///   calculated.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static double[][] CumulativeSum(this double[][] matrix, int dimension)
        {
            int rows = matrix.Rows();
            int cols = matrix.Columns();
            if (dimension == 1)
                return CumulativeSum(matrix, dimension, Jagged.Zeros<double>(rows, cols));
            return CumulativeSum(matrix, dimension, Jagged.Zeros<double>(cols, rows));
        }        

        /// <summary>
        ///   Matrix cumulative sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose cumulative sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the cumulative will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static double[][] CumulativeSum(this double[][] matrix, int dimension, double[][] result)
        {
            int rows = matrix.Rows();
            int cols = matrix.Columns();

            if (dimension == 1)
            {
                matrix.GetRow(0, result: result[0]);
                for (int i = 1; i < rows; i++)
                    for (int j = 0; j < cols; j++)
                        result[i][j] = (double)(result[i - 1][j] + matrix[i][j]);
            }
            else if (dimension == 0)
            {
                matrix.GetColumn(0, result: result[0]);
                for (int i = 1; i < cols; i++)
                    for (int j = 0; j < rows; j++)
                        result[i][j] = (double)(result[i - 1][j] + matrix[j][i]);
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix cumulative sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose cumulative sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the cumulative will be
        ///   calculated.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static double[,] CumulativeSum(this double[,] matrix, int dimension)
        {
            int rows = matrix.Rows();
            int cols = matrix.Columns();
            if (dimension == 1)
                return CumulativeSum(matrix, dimension, Matrix.Zeros<double>(rows, cols));
            return CumulativeSum(matrix, dimension, Matrix.Zeros<double>(cols, rows)); 
        }        

        /// <summary>
        ///   Matrix cumulative sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose cumulative sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the cumulative will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static double[,] CumulativeSum(this double[,] matrix, int dimension, double[,] result)
        {
            int rows = matrix.Rows();
            int cols = matrix.Columns();

            if (dimension == 1)
            {
                result.SetColumn(0, matrix.GetRow(0));
                for (int i = 1; i < rows; i++)
                    for (int j = 0; j < cols; j++)
                        result[i, j] = (double)(result[i - 1, j] + matrix[i, j]);
            }
            else if (dimension == 0)
            {
                result.SetColumn(0, matrix.GetColumn(0));
                for (int i = 1; i < cols; i++)
                    for (int j = 0; j < rows; j++)
                        result[i, j] = (double)(result[i - 1, j] + matrix[j, i]);
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix cumulative sum.
        /// </summary>
        ///
        /// <param name="vector">A vector whose cumulative sum will be calculated.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static long[] CumulativeSum(this long[] vector)
        {
            if (vector.Length == 0)
                return new long[0];

            return CumulativeSum(vector, Accord.Math.Vector.CreateAs(vector));
        }

        /// <summary>
        ///   Matrix cumulative sum.
        /// </summary>
        ///
        /// <param name="vector">A vector whose cumulative sum will be calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static long[] CumulativeSum(this long[] vector, long[] result)
        {
            result[0] = vector[0];
            for (int i = 1; i < vector.Length; i++)
                result[i] = (long)(result[i - 1] + vector[i]);
            return result;
        }

        /// <summary>
        ///   Matrix cumulative sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose cumulative sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the cumulative will be
        ///   calculated.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static long[][] CumulativeSum(this long[][] matrix, int dimension)
        {
            int rows = matrix.Rows();
            int cols = matrix.Columns();
            if (dimension == 1)
                return CumulativeSum(matrix, dimension, Jagged.Zeros<long>(rows, cols));
            return CumulativeSum(matrix, dimension, Jagged.Zeros<long>(cols, rows));
        }        

        /// <summary>
        ///   Matrix cumulative sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose cumulative sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the cumulative will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static long[][] CumulativeSum(this long[][] matrix, int dimension, long[][] result)
        {
            int rows = matrix.Rows();
            int cols = matrix.Columns();

            if (dimension == 1)
            {
                matrix.GetRow(0, result: result[0]);
                for (int i = 1; i < rows; i++)
                    for (int j = 0; j < cols; j++)
                        result[i][j] = (long)(result[i - 1][j] + matrix[i][j]);
            }
            else if (dimension == 0)
            {
                matrix.GetColumn(0, result: result[0]);
                for (int i = 1; i < cols; i++)
                    for (int j = 0; j < rows; j++)
                        result[i][j] = (long)(result[i - 1][j] + matrix[j][i]);
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix cumulative sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose cumulative sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the cumulative will be
        ///   calculated.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static long[,] CumulativeSum(this long[,] matrix, int dimension)
        {
            int rows = matrix.Rows();
            int cols = matrix.Columns();
            if (dimension == 1)
                return CumulativeSum(matrix, dimension, Matrix.Zeros<long>(rows, cols));
            return CumulativeSum(matrix, dimension, Matrix.Zeros<long>(cols, rows)); 
        }        

        /// <summary>
        ///   Matrix cumulative sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose cumulative sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the cumulative will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static long[,] CumulativeSum(this long[,] matrix, int dimension, long[,] result)
        {
            int rows = matrix.Rows();
            int cols = matrix.Columns();

            if (dimension == 1)
            {
                result.SetColumn(0, matrix.GetRow(0));
                for (int i = 1; i < rows; i++)
                    for (int j = 0; j < cols; j++)
                        result[i, j] = (long)(result[i - 1, j] + matrix[i, j]);
            }
            else if (dimension == 0)
            {
                result.SetColumn(0, matrix.GetColumn(0));
                for (int i = 1; i < cols; i++)
                    for (int j = 0; j < rows; j++)
                        result[i, j] = (long)(result[i - 1, j] + matrix[j, i]);
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix cumulative sum.
        /// </summary>
        ///
        /// <param name="vector">A vector whose cumulative sum will be calculated.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static decimal[] CumulativeSum(this decimal[] vector)
        {
            if (vector.Length == 0)
                return new decimal[0];

            return CumulativeSum(vector, Accord.Math.Vector.CreateAs(vector));
        }

        /// <summary>
        ///   Matrix cumulative sum.
        /// </summary>
        ///
        /// <param name="vector">A vector whose cumulative sum will be calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static decimal[] CumulativeSum(this decimal[] vector, decimal[] result)
        {
            result[0] = vector[0];
            for (int i = 1; i < vector.Length; i++)
                result[i] = (decimal)(result[i - 1] + vector[i]);
            return result;
        }

        /// <summary>
        ///   Matrix cumulative sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose cumulative sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the cumulative will be
        ///   calculated.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static decimal[][] CumulativeSum(this decimal[][] matrix, int dimension)
        {
            int rows = matrix.Rows();
            int cols = matrix.Columns();
            if (dimension == 1)
                return CumulativeSum(matrix, dimension, Jagged.Zeros<decimal>(rows, cols));
            return CumulativeSum(matrix, dimension, Jagged.Zeros<decimal>(cols, rows));
        }        

        /// <summary>
        ///   Matrix cumulative sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose cumulative sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the cumulative will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static decimal[][] CumulativeSum(this decimal[][] matrix, int dimension, decimal[][] result)
        {
            int rows = matrix.Rows();
            int cols = matrix.Columns();

            if (dimension == 1)
            {
                matrix.GetRow(0, result: result[0]);
                for (int i = 1; i < rows; i++)
                    for (int j = 0; j < cols; j++)
                        result[i][j] = (decimal)(result[i - 1][j] + matrix[i][j]);
            }
            else if (dimension == 0)
            {
                matrix.GetColumn(0, result: result[0]);
                for (int i = 1; i < cols; i++)
                    for (int j = 0; j < rows; j++)
                        result[i][j] = (decimal)(result[i - 1][j] + matrix[j][i]);
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }

        /// <summary>
        ///   Matrix cumulative sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose cumulative sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the cumulative will be
        ///   calculated.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static decimal[,] CumulativeSum(this decimal[,] matrix, int dimension)
        {
            int rows = matrix.Rows();
            int cols = matrix.Columns();
            if (dimension == 1)
                return CumulativeSum(matrix, dimension, Matrix.Zeros<decimal>(rows, cols));
            return CumulativeSum(matrix, dimension, Matrix.Zeros<decimal>(cols, rows)); 
        }        

        /// <summary>
        ///   Matrix cumulative sum.
        /// </summary>
        ///
        /// <param name="matrix">A matrix whose cumulative sum will be calculated.</param>
        /// <param name="dimension">The dimension in which the cumulative will be
        ///   calculated.</param>
        /// <param name="result">A location where the result of this operation will be stored,
        ///   avoiding unnecessary memory allocations.</param>
        ///
#if NET45 || NET46 || NET462 || NETSTANDARD2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public static decimal[,] CumulativeSum(this decimal[,] matrix, int dimension, decimal[,] result)
        {
            int rows = matrix.Rows();
            int cols = matrix.Columns();

            if (dimension == 1)
            {
                result.SetColumn(0, matrix.GetRow(0));
                for (int i = 1; i < rows; i++)
                    for (int j = 0; j < cols; j++)
                        result[i, j] = (decimal)(result[i - 1, j] + matrix[i, j]);
            }
            else if (dimension == 0)
            {
                result.SetColumn(0, matrix.GetColumn(0));
                for (int i = 1; i < cols; i++)
                    for (int j = 0; j < rows; j++)
                        result[i, j] = (decimal)(result[i - 1, j] + matrix[j, i]);
            }
            else
            {
                throw new ArgumentException("Invalid dimension", "dimension");
            }

            return result;
        }
    }
}